home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Whiteline: delta
/
whiteline CD Series - delta.iso
/
systems
/
unixtkit
/
wc
/
wc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-25
|
5KB
|
266 lines
/****************************************************************/
/* Count the characters, words and lines in a file. */
/* */
/* By David Megginson, 1991 */
/* Released into the public domain. */
/* */
/* Command line options: */
/* -c Count characters */
/* -w Count words */
/* -l Count lines */
/* (count everything by default) */
/* */
/* Makefile options: */
/* -DBUFFER_SIZE=n Read n bytes at a time */
/* -DSKIP_CR Ignore carriage returns */
/****************************************************************/
/* $Id: wc.c,v 1.2 1991/03/05 09:02:30 david Exp david $ */
/*
* $Log: wc.c,v $
* Revision 1.2 1991/03/05 09:02:30 david
* Changed `static version' to `static char * version' (duh!)
*
* Revision 1.1 1991/03/05 08:59:46 david
* Initial revision
*
*/
static char * version = "$Id: wc.c,v 1.2 1991/03/05 09:02:30 david Exp david $";
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
/* The string of legal options for getopt */
#define OPTSTRING "clw"
/* The size of the read() buffer. Allow the user to define */
/* this in the Makefile if desired. */
#ifndef BUFFER_SIZE
#define BUFFER_SIZE 50000L
#endif
/* Use this buffer to read in the file */
static char buffer[BUFFER_SIZE];
/* Number of files read so far, and running totals */
static int total_files = 0;
static long total_characters = 0;
static long total_words = 0;
static long total_lines = 0;
/* Flags controlled by command-line options */
static int all_flag = 1; /* count everything (default) */
static int c_flag = 0; /* count characters */
static int w_flag = 0; /* count words */
static int l_flag = 0; /* count lines */
static int whitespace_flag = 1; /* whitespace seen */
static int nl_flag = 0; /* newline seen */
/* getopt() stuff */
extern int optind;
/* Local functions */
static void do_file( const char * filename,int fd );
static void count_buffer( long * c,long * w,long * l,fpos_t length );
static void show_results( long c,long w,long l,const char * filename );
static void show_totals( void );
main( int ac,const char ** av )
{
int opt,current,fd;
opt = getopt(ac,av,OPTSTRING);
while( opt != EOF ) {
switch( opt ) {
case 'c':
all_flag = 0;
c_flag = 1;
break;
case 'l':
all_flag = 0;
l_flag = 1;
break;
case 'w':
all_flag = 0;
w_flag = 1;
break;
}
opt = getopt(ac,av,OPTSTRING);
}
if( optind == ac ) {
do_file(NULL,0);
} else for( current = optind; current < ac; current++ ) {
if( !strcmp(av[current],"-") )
do_file(av[current],0);
else {
fd = open(av[current],O_RDONLY);
if( fd < 0 ) {
perror(av[current]);
exit(1);
}
do_file(av[current],fd);
close(fd);
}
}
if( total_files > 1 )
show_totals();
return 0;
}
/*******
Count the words in a single file.
Arguments: const char * filename the file name
int fd the file descriptor
Return value: none
*******/
static void
do_file( const char * filename,int fd )
{
fpos_t total_read;
long c=0, w=0, l=0;
whitespace_flag = 1;
total_files++;
do {
total_read = read(fd,buffer,BUFFER_SIZE);
#if DEBUG
printf("Read %ld characters from %s\n",total_read,filename?filename:"stdin");
#endif
if( total_read > 0 )
count_buffer(&c,&w,&l,total_read);
} while( total_read == BUFFER_SIZE );
/* if the file ended on a word, count that word too */
if( !whitespace_flag )
w++;
/* if the last character was not NL, count the last */
/* line */
if( !nl_flag )
l++;
show_results(c,w,l,filename);
total_characters += c;
total_words += w;
total_lines += l;
}
/*******
Count the buffer itself.
Arguments: long * c characters
long * w words
long * l lines
fpos_t length characters in buffer
Return value: none
*******/
void
count_buffer( long * c,long * w,long * l,fpos_t length )
{
fpos_t pos;
for( pos = 0; pos < length; pos++ ) {
switch( buffer[pos] ) {
#ifdef SKIP_CR
case '\r':
break;
#endif
case '\n':
(*l)++;
if( !whitespace_flag )
(*w)++;
whitespace_flag = 1;
nl_flag = 1;
break;
case ' ':
case '\t':
if( !whitespace_flag )
(*w)++;
whitespace_flag = 1;
break;
default:
whitespace_flag = 0;
break;
}
/* Always count a character */
(*c)++;
}
}
/*******
Show the results for a file.
Arguments: long c characters
long w words
long l lines
const char * filename
Return value: none
*******/
void
show_results( long c,long w,long l,const char * filename )
{
if( all_flag || l_flag )
printf("%10ld",l);
if( all_flag || w_flag )
printf("%10ld",w);
if( all_flag || c_flag )
printf("%10ld",c);
if( filename )
printf(" %s",filename);
printf("\n");
}
/*******
Show the final total for more than one file.
Arguments: none
Return value: none
*******/
void
show_totals()
{
if( all_flag || l_flag )
printf("%10ld",total_lines);
if( all_flag || w_flag )
printf("%10ld",total_words);
if( all_flag || c_flag )
printf("%10ld",total_characters);
printf(" TOTAL\n");
}